package logicals

import (
	"easyblog/models"
	"easyblog/utils/db"
	"easyblog/utils/errmsg"
	"easyblog/utils/es"
	"easyblog/utils/log"
	"gorm.io/gorm"
)

type ArticleLogic struct {}

var DefaultArticle = ArticleLogic{}

/**
* CreateArticle
* @Description: 新建文章
* @receiver this
* @param article
* @return int
*/
func (this *ArticleLogic)CreateArticle(article *models.Article) int  {
	err := db.Db.Create(article).Error
	if err != nil {
		return errmsg.ERROR
	}

	go updateCateNum(article.Cid,"+")
	go updateTagsNum(article.Tids,"+")

	go es.CreateArticle(article)
	return errmsg.SUCCSE
}

/**
* EditArticle
* @Description: 编辑文章
* @receiver this
* @param articleId
* @param article
* @return int
*/
func (this *ArticleLogic) EditArticle(articleId int, article *models.Article) int {

	var maps = make(map[string]interface{})
	maps["title"] = article.Title
	maps["cid"] = article.Cid
	maps["tids"] = article.Tids
	maps["desc"] = article.Desc
	maps["content"] = article.Content
	maps["status"] = article.Status
	
	err := db.Db.Model(&models.Article{}).Where("id = ?", articleId).Updates(maps).Error
	if err != nil {
		log.Logger.Error(err.Error())
		return errmsg.ERROR
	}
	go es.EditArticle(article)
	return errmsg.SUCCSE
}

/**
* GetOneArticleById
* @Description: 根据ID查询文章
* @receiver this
* @param articleId
* @return models.Article
* @return int
*/
func (this *ArticleLogic) GetArticleById(articleId int) (models.Article , int) {
	var article models.Article

	err := db.Db.Where("id = ?", articleId).First(&article).Error

	if err != nil {
		log.Logger.Error(err.Error())
		return article, errmsg.ERROR
	}

	go increaseArticleView(article.ID)

	article.Category,_=DefaultCategory.GetCategoryById(article.Cid)
	article.Tags,_= DefaultTag.GetTagsByIds(article.Tids)

	return article,errmsg.SUCCSE
}

/**
* DeleteArticle
* @Description: 删除文章
* @receiver this
* @param id
* @return int
*/
func (this *ArticleLogic) DeleteArticle(articleId int) int {

	// 文章删除后，对应的cate和tag中的文章数量也减少
	var article models.Article
	err := db.Db.Where("id = ?", articleId).First(&article).Error
	go updateCateNum(article.Cid,"-")
	go updateTagsNum(article.Tids,"-")

	err = db.Db.Where("id = ?", articleId).Delete(&models.Article{}).Error
	if err != nil {
		log.Logger.Error(err.Error())
		return errmsg.ERROR
	}
	go es.DeleteArticle(articleId)
	return errmsg.SUCCSE
}

/**
* GetArticles
* @Description: 分页查询
* @receiver this
* @param pageSize
* @param pageNum
* @return []models.Article
* @return int
* @return int64
*/
func (this *ArticleLogic) GetPageArticles(pageSize int, pageNum int) ([]models.Article,int,int64){
	var articleList []models.Article
	var total int64
	err := db.Db.Limit(pageSize).Offset(pageSize * (pageNum - 1)).Find(&articleList).Error
	db.Db.Model(&models.Article{}).Count(&total)
	if err != nil && gorm.ErrRecordNotFound != nil {
		return nil, errmsg.ERROR, 0
	}
	for i := 0 ;i<len(articleList); i++{
		articleList[i].Category,_ = DefaultCategory.GetCategoryById(articleList[i].Cid)
		articleList[i].Tags,_ = DefaultTag.GetTagsByIds(articleList[i].Tids)
	}
	return articleList, errmsg.SUCCSE, total
}

/**
* UpdateTop
* @Description: 更新文章的顶置
* @receiver this
* @param id
* @param top
* @return int
*/
func (this *ArticleLogic) UpdateTop(id int, top int) int {
	var maps = make(map[string]interface{})
	maps["top"] = top

	err := db.Db.Model(&models.Article{}).Where("id = ?", id).Updates(maps).Error
	if err != nil {
		log.Logger.Error(err.Error())
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

/**
* UpdateReward
* @Description: 更新文章的打赏
* @receiver this
* @param id
* @param reward
* @return int
*/
func (this *ArticleLogic) UpdateReward(id int, reward int) int {
	var maps = make(map[string]interface{})
	maps["reward"] = reward

	err := db.Db.Model(&models.Article{}).Where("id = ?", id).Updates(maps).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

/**
* SearchArticles
* @Description: 通过es返回的ids，查询
* @receiver this
* @param keyWords
* @return []models.Article
* @return int
* @return int64
*/
func (this *ArticleLogic) SearchArticles(keyWords string) ([]models.Article,int,int64) {
	articleIds, _ := es.SearchArticle(keyWords)
	var articleList []models.Article

	err := db.Db.Model(&models.Article{}).Where(articleIds).Find(&articleList).Error
	if err != nil {
		return nil,errmsg.ERROR,0
	}
	for i := 0 ;i<len(articleList); i++{
		articleList[i].Category,_ = DefaultCategory.GetCategoryById(articleList[i].Cid)
		articleList[i].Tags,_ = DefaultTag.GetTagsByIds(articleList[i].Tids)
	}
	return articleList,200,(int64)(len(articleIds))
}

/**
* GetHotArticle
* @Description: 根据浏览量获得热门文章
* @receiver this
* @return []models.Article
* @return int
*/
func (this *ArticleLogic) GetHotArticles() ([]models.Article,int) {
	var articleList []models.Article
	err := db.Db.Order("view_num desc").Limit(10).Find(&articleList).Error
	if err != nil {
		return nil,errmsg.ERROR
	}
	return articleList,errmsg.SUCCSE
}

/**
* increaseArticleView
* @Description: 文章浏览数+1
* @param articleId
*/
func increaseArticleView(articleId uint ){
	err := db.Db.Model(&models.Article{}).Where("id = ?", articleId).UpdateColumn("view_num", gorm.Expr("view_num + 1")).Error
	if err != nil {
		return
	}
	return
}